#import "FlutterHuaweiCloudPlugin.h"

@implementation FlutterHuaweiCloudPlugin


+ (void)load {
    [OBSClient class];
}

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel* channel = [FlutterMethodChannel
                                     methodChannelWithName:@"flutter_huawei_cloud"
                                     binaryMessenger:[registrar messenger]];
    FlutterHuaweiCloudPlugin* instance = [[FlutterHuaweiCloudPlugin alloc] init];
    FlutterEventChannel *eventChannel = [FlutterEventChannel
                                         eventChannelWithName:@"flutter_huawei_cloud_progress"
                                         binaryMessenger: [registrar messenger]];
    [eventChannel setStreamHandler:instance];
    [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    if ([@"initialize" isEqualToString:call.method]) {
        [self initializeWithMethodCall:call result:result];
    } else if ([@"uploadFile" isEqualToString:call.method]) {
        [self uploadFileWithMethodCall:call result:result];
    } else if ([@"uploadMultipleFile" isEqualToString:call.method]) {
        [self uploadMultipleFileWithMethodCall:call result:result];
    } else if ([@"getPlatformVersion" isEqualToString:call.method]) {
        result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
    } else {
        result(FlutterMethodNotImplemented);
    }
}

- (void)initializeWithMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
    id args = call.arguments;
    if (args == NULL && ![args isKindOfClass:[NSDictionary class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"参数格式错误" details:NULL]);
        return;
    }
    
    id accessKey = args[@"accessKey"];
    if (accessKey == NULL && ![accessKey isKindOfClass:[NSString class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"accessKey不可为空" details:NULL]);
        return;
    }
    id secretKey = args[@"secretKey"];
    if (secretKey == NULL && ![secretKey isKindOfClass:[NSString class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"secretKey不可为空" details:NULL]);
        return;
    }
    id region = args[@"region"];
    if (region == NULL && ![region isKindOfClass:[NSString class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"region不可为空" details:NULL]);
        return;
    }
    self.region = region;
    
    OBSStaticCredentialProvider *provider = [[OBSStaticCredentialProvider alloc] initWithAccessKey:accessKey secretKey:secretKey];
    
    NSString *endPoint = [NSString stringWithFormat:@"https://obs.%@.myhuaweicloud.com", region];
    OBSServiceConfiguration *config = [[OBSServiceConfiguration alloc] initWithURLString:endPoint credentialProvider:provider];
    self.obsClient = [[OBSClient alloc] initWithConfiguration:config];
    result(NULL);
}

- (void)uploadFileWithMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
    id args = call.arguments;
    if (args == NULL && ![args isKindOfClass:[NSDictionary class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"参数格式错误" details:NULL]);
        return;
    }
    
    id bucketName = args[@"bucketName"];
    if (bucketName == NULL && ![bucketName isKindOfClass:[NSString class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"bucketName不可为空" details:NULL]);
        return;
    }
    id objectKey = args[@"objectKey"];
    if (objectKey == NULL && ![objectKey isKindOfClass:[NSString class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"objectKey不可为空" details:NULL]);
        return;
    }
    id filePath = args[@"filePath"];
    if (filePath == NULL && ![filePath isKindOfClass:[NSString class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"filePath不可为空" details:NULL]);
        return;
    }
    
    NSString *remoteUrl = [NSString stringWithFormat:@"https://%@.obs.%@.myhuaweicloud.com/%@", bucketName, self.region, objectKey];
    NSLog(@"开始上传：%@", remoteUrl);
    
    OBSPutObjectWithFileRequest *request = [[OBSPutObjectWithFileRequest alloc] initWithBucketName:bucketName objectKey:objectKey uploadFilePath:filePath];
    request.background = YES;
    __weak typeof(self) weakSelf = self;
    request.uploadProgressBlock = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
        NSLog(@"bytesSent: %lld, totalBytesSent: %lld, totalBytesExpectedToSend: %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
        //        NSLog(@"%0.1f%%",(float)floor(totalBytesSent*10000/totalBytesExpectedToSend)/100);
//        self.eventSink(@{@"objectKey": objectKey, @"bytesSent": @(totalBytesSent), @"totalBytes": @(totalBytesExpectedToSend)});
        // 弱引用避免循环引用
        typeof(self) strongSelf = weakSelf;
        if (!strongSelf) return;
        
        if (!strongSelf.eventSink) return;
                
        // 安全发送事件
        dispatch_async(dispatch_get_main_queue(), ^{
            strongSelf.eventSink(@{
                @"type": @"progress",
                @"objectKey": objectKey,
                @"bytesSent": @(totalBytesSent),
                @"totalBytes": @(totalBytesExpectedToSend)
            });
        });
    };
    
    [self.obsClient putObject:request completionHandler:^(OBSPutObjectResponse *response, NSError *error) {
        if (error) {
            // 打印错误信息
            NSLog(@"文件上传失败");
            NSLog(@"%@",error);
            result(NULL);
        }
        if ([response.statusCode isEqualToString:@"200"]) {
            NSLog(@"文件上传成功");
            NSLog(@"%@", response);
            NSLog(@"%@", response.etag);
            result(remoteUrl);
        }
    }];
}

- (void)uploadMultipleFileWithMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
    id args = call.arguments;
    if (args == NULL && ![args isKindOfClass:[NSDictionary class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"参数格式错误" details:NULL]);
        return;
    }
    
    id bucketName = args[@"bucketName"];
    if (bucketName == NULL && ![bucketName isKindOfClass:[NSString class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"bucketName不可为空" details:NULL]);
        return;
    }
    id files = args[@"files"];
    if (files == NULL && ![files isKindOfClass:[NSArray class]]) {
        result([FlutterError errorWithCode:@"InvalidArgument" message:@"files不可为空" details:NULL]);
        return;
    }
    
    // 创建线程安全的结果容器
    NSMutableDictionary<NSString *, NSString *> *results = [NSMutableDictionary dictionary];
    __block NSUInteger completedCount = 0;
    NSUInteger totalCount = [(NSArray *)files count];
    dispatch_queue_t syncQueue = dispatch_queue_create("com.example.uploadQueue", DISPATCH_QUEUE_SERIAL);
    
    // 创建任务组
    dispatch_group_t uploadGroup = dispatch_group_create();
    
    for (NSDictionary *fileInfo in files) {
        // 文件参数校验
        NSString *objectKey = fileInfo[@"objectKey"];
        NSString *filePath = fileInfo[@"filePath"];
        
        // if (![objectKey isKindOfClass:[NSString class]] || objectKey.length == 0 ||
        //     ![filePath isKindOfClass:[NSString class]] || filePath.length == 0) {
        //     NSLog(@"Invalid file parameters: %@", fileInfo);
        //     continue;
        // }
        
        // 构造远程URL
        NSString *remoteUrl = [NSString stringWithFormat:@"https://%@.obs.%@.myhuaweicloud.com/%@",
                               bucketName, self.region, objectKey];
        
        // 创建上传请求
        OBSPutObjectWithFileRequest *request = [[OBSPutObjectWithFileRequest alloc]
                                                initWithBucketName:bucketName
                                                objectKey:objectKey
                                                uploadFilePath:filePath];
        request.background = YES;
        
        // 进度处理（需要主线程）
        __weak typeof(self) weakSelf = self;
        request.uploadProgressBlock = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
            // 弱引用避免循环引用
            typeof(self) strongSelf = weakSelf;
            if (!strongSelf) return;
            
            if (!strongSelf.eventSink) return;
            dispatch_async(dispatch_get_main_queue(), ^{
                strongSelf.eventSink(@{
                    @"objectKey": objectKey,
                    @"bytesSent": @(totalBytesSent),
                    @"totalBytes": @(totalBytesExpectedToSend)
                });
            });
        };
        
        // 加入任务组
        dispatch_group_enter(uploadGroup);
        
        // 执行上传
        [self.obsClient putObject:request completionHandler:^(OBSPutObjectResponse *response, NSError *error) {
            // 使用串行队列保证线程安全
            dispatch_async(syncQueue, ^{
                
                // 弱引用避免循环引用
                typeof(self) strongSelf = weakSelf;
                
                if (!error && [response.statusCode isEqualToString:@"200"]) {
                    results[objectKey] = remoteUrl;
                    NSLog(@"文件 %@ 上传成功", objectKey);
                    
                    // 更新完成计数并发送进度
                    completedCount++;
                    
                    if (strongSelf && strongSelf.eventSink) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            strongSelf.eventSink(@{
                                @"completed": @(completedCount),
                                @"total": @(totalCount),
                                @"progress": @((float)completedCount / totalCount)
                            });
                        });
                    }
                    
                } else {
                    NSString *errorMsg = error ? error.localizedDescription : @"未知错误";
                    NSLog(@"文件 %@ 上传失败: %@", objectKey, errorMsg);
                }
                dispatch_group_leave(uploadGroup);
            });
        }];
    }
    
    // 所有任务完成回调
    dispatch_group_notify(uploadGroup, dispatch_get_main_queue(), ^{
        result([results copy]);
    });
}

- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
    self.eventSink = events;
    return NULL;
}

- (FlutterError *)onCancelWithArguments:(id)arguments {
    self.eventSink = NULL;
    return NULL;
}


@end
